#include    "utils.h"
#include	<cstring>
#include	<cstdlib>

#if defined(_WIN32)
#	include	<Windows.h>
#else
#	include	<uuid/uuid.h>
#endif

/** Fix for strtod, strtoll, strtoull missing on Windows **/
#if defined(_WIN32)
extern "C" __declspec(dllexport) double s2d(const char * data, char ** end) { return strtod(data, end); }
extern "C" __declspec(dllexport) int64_t s2ll(const char * data, char ** end, int base) { return strtoll(data, end, base); }
extern "C" __declspec(dllexport) uint64_t s2ull(const char * data, char ** end, int base) { return strtoull(data, end, base); }
#endif

std::string CreateId() {
    char		hex[64];
	uint32_t	data[4];

#if defined(_WIN32)
	GUID guid;
	::CoInitialize(NULL);
	::CoCreateGuid(&guid);
	::CoUninitialize();
	::memcpy(data, &guid, 16);
#else
	uuid_t uuid;
	uuid_generate(uuid);
	::memcpy(data, uuid, 16);
#endif

    snprintf(hex, 64, "%08X%08X%08X%08X", data[0], data[1], data[2], data[3]);
	return std::string(hex);
}

std::vector<std::string> Split(const std::string & s, const std::string & delim, bool ignore_empty /* = true */) {
	std::vector<std::string> ret;

	std::string::size_type start = 0, end = 0;
	while (end < s.length()) {
		char ch = s[end];
		if (delim.find(ch) != std::string::npos) {
			if (start != end) ret.push_back(s.substr(start, end - start));
			else if(!ignore_empty) ret.push_back("");
			++end;
			start = end;
		} else {
			++end;
		}
	}

	if (start != end) ret.push_back(s.substr(start));
	return ret;
}